package hu.issue.framework.web.tag;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collection;

public class SelectTag extends FormElementTag {
	private Collection<?> items;
	private String valueProperty;
	private String contentProperty;

	public void setItems(final Collection<?> items) {
		this.items = items;
	}

	public void setValueProperty(final String property) {
		this.valueProperty = property;
	}

	public void setContentProperty(final String property) {
		this.contentProperty = property;
	}

	@Override
	protected String getTagName() {
		return "select";
	}

	@Override
	protected String getTagContent() {
		Method valueMethod = null;
		Method contentMethod = null;
		final StringBuilder builder = new StringBuilder();
		for (final Object obj : this.items) {
			if (valueMethod == null) {
				valueMethod = getMethod(obj, this.valueProperty);
				contentMethod = getMethod(obj, this.contentProperty);
			}
			final Object value = invokeMethod(obj, valueMethod);
			final Object content = invokeMethod(obj, contentMethod);
			builder.append(String.format("<option value=\"%s\">%s</option>", value, content));
		}

		return builder.toString();
	}

	private Object invokeMethod(final Object obj, final Method method) {
		try {
			return method.invoke(obj);
		} catch (final RuntimeException e) {
			throw e;
		} catch (final Exception e) {
			throw new RuntimeException(e);
		}
	}

	private Method getMethod(final Object obj, final String property) {
		try {
			final BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			for (final PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {
				if (descriptor.getName().equals(property)) {
					return descriptor.getReadMethod();
				}

			}
		} catch (final IntrospectionException e) {
			throw new RuntimeException(e);
		}

		throw new IllegalArgumentException(String.format("Unknown property: %s, object: %s", property, obj));
	}
}
